/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lomtools.persistence;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author Leonardo Oliveira Moreira
 * 
 */
public final class BeanUtils {

    private BeanUtils() {
        
    }

    public static final List requestToBeanList(HttpServletRequest request, Class objClass, String parameter) throws BeanException {
        List<Bean> resultList = new ArrayList<Bean>();
        String strItemSelecteds = request.getParameter(parameter);
        String[] listItems = BeanUtils.stringToStringArray(strItemSelecteds, ",");
        for (String item : listItems) {
            Bean bean = null;
            try {
                bean = (Bean) objClass.newInstance();
            } catch (InstantiationException ex) {
                throw new BeanException(ex);
            } catch (IllegalAccessException ex) {
                throw new BeanException(ex);
            }
            Field[] declaredFields = bean.getClass().getDeclaredFields();
            for (Field f : declaredFields) {
                Annotation[] declaredAnnotations = f.getDeclaredAnnotations();
                for (Annotation a : declaredAnnotations) {
                    if (a.annotationType() == javax.persistence.Id.class) {
                        try {
                            f.setAccessible(true);
                            if (item != null && f.getType() == java.lang.Integer.class) {
                                f.set(bean, Integer.parseInt(item));
                            }
                            if (item != null && f.getType() == java.lang.Double.class) {
                                f.set(bean, Double.parseDouble(item));
                            }
                            if (item != null && f.getType() == java.lang.Long.class) {
                                f.set(bean, Long.parseLong(item));
                            }
                            if (item != null && f.getType() == java.lang.Boolean.class) {
                                f.set(bean, Boolean.parseBoolean(item));
                            }
                            if (item != null && f.getType() == java.lang.Float.class) {
                                f.set(bean, Float.parseFloat(item));
                            }
                            if (item != null && f.getType() == java.util.Date.class) {
                                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                                try {
                                    f.set(bean, sdf.parse(item));
                                } catch (ParseException ex) {
                                    f.set(bean, null);
                                }
                            }
                            if (item != null && f.getType() == java.lang.String.class) {
                                f.set(bean, item);
                            }
                        } catch (IllegalArgumentException ex) {
                            throw new BeanException(ex);
                        } catch (IllegalAccessException ex) {
                            throw new BeanException(ex);
                        }
                    }
                }
            }
            if (bean != null)
                resultList.add(bean);
        }
        return resultList;
    }

    public static final Bean requestToBean(HttpServletRequest request, Class objClass) throws BeanException {
        try {
            Enumeration requestParameterNames = request.getParameterNames();
            List<String> parametersNames = new ArrayList<String>();
            while (requestParameterNames.hasMoreElements()) {
                parametersNames.add((String) requestParameterNames.nextElement());
            }
            Class classObject = Class.forName(objClass.getCanonicalName());
            Bean bean = (Bean) classObject.newInstance();
            Method[] methods = classObject.getMethods();
            for (Method m : methods) {
                if (m.getName().startsWith("set")) {
                    for (String element : parametersNames) {
                        if (m.getName().contains("set" + element.substring(0, 1).toUpperCase() + element.substring(1))) {
                            if (m.getParameterTypes().length == 1) {
                                try {
                                    m.setAccessible(true);
                                    String value = request.getParameter(element);
                                    if (value != null && value.trim().length() == 0)
                                        value = null;
                                    if (m.getParameterTypes()[0].getName().equals("java.lang.Integer")) {
                                        m.invoke(bean, (value == null ? value : Integer.parseInt(value)));
                                        break;
                                    }
                                    if (m.getParameterTypes()[0].getName().equals("java.lang.Double")) {
                                        m.invoke(bean, (value == null ? value : Double.parseDouble(value)));
                                        break;
                                    }
                                    if (m.getParameterTypes()[0].getName().equals("java.lang.Boolean")) {
                                        m.invoke(bean, (value == null ? value : Boolean.parseBoolean(value)));
                                        break;
                                    }
                                    if (m.getParameterTypes()[0].getName().equals("java.lang.Float")) {
                                        m.invoke(bean, (value == null ? value : Float.parseFloat(value)));
                                        break;
                                    }
                                    if (m.getParameterTypes()[0].getName().equals("java.lang.Long")) {
                                        m.invoke(bean, (value == null ? value : Long.parseLong(value)));
                                        break;
                                    }
                                    if (m.getParameterTypes()[0].getName().equals("java.util.Date")) {
                                        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                                        try {
                                            m.invoke(bean, (value == null ? value : sdf.parse(value)));
                                        } catch (ParseException ex) {
                                            throw new BeanException(ex);
                                        }
                                        break;
                                    }
                                    m.invoke(bean, value);
                                } catch (IllegalAccessException ex) {
                                    throw new BeanException(ex);
                                } catch (IllegalArgumentException ex) {
                                    throw new BeanException(ex);
                                } catch (InvocationTargetException ex) {
                                    throw new BeanException(ex);
                                }
                            } else {
                                throw new BeanException("Parameter types > 1");
                            }
                        }
                    }
                }
            }
            // return the JavaBean
            return bean;
        } catch (InstantiationException ex) {
            throw new BeanException(ex);
        } catch (IllegalAccessException ex) {
            throw new BeanException(ex);
        } catch (ClassNotFoundException ex) {
            throw new BeanException(ex);
        }
    }

    public static final String getAttributeName(Bean bean, String columnName) {
        Field[] declaredFields = bean.getClass().getDeclaredFields();
        String attributeName = null;
        for (Field f : declaredFields) {
            Annotation[] declaredAnnotations = f.getDeclaredAnnotations();
            for (Annotation a : declaredAnnotations) {
                if (a.annotationType() == javax.persistence.Column.class) {
                    javax.persistence.Column c = (javax.persistence.Column) a;
                    if (columnName.equals(c.name())) {
                        return f.getName();
                    }
                }
            }
        }
        return attributeName;
    }

    public static final String[] stringToStringArray(String string, String delimiter) {
        String[] listItems = null;
        if (string != null && string.trim().length() > 0 && string.indexOf(delimiter) != -1) {
            listItems = string.split(delimiter);
        } else {
            if (string != null && string.trim().length() > 0) {
                listItems = new String[]{string};
            }
        }
        return listItems;
    }

}